package com.wanli.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wanli.common.Const;
import com.wanli.common.Result;
import com.wanli.domain.entity.Role;
import com.wanli.domain.entity.User;
import com.wanli.domain.entity.UserRole;
import com.wanli.service.RoleService;
import com.wanli.service.UserRoleService;
import com.wanli.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import com.wanli.common.BaseController;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author Byterain
 * @since 2023-12-06
 */
@RestController
@RequestMapping("/user")
public class UserController extends BaseController {
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;
    @Autowired
    PasswordEncoder passwordEncoder;
    @Autowired
    UserRoleService userRoleService;

    // 保存用户分配角色
    @Transactional
    @PostMapping("/role/{id}")
    public Result role(@PathVariable Long id, @RequestBody Long[] roleIds) {
        // 封装关系表: sys_user_role
        List<UserRole> userRoleList = new ArrayList<>();
        Arrays.stream(roleIds).forEach(roleId -> {
            UserRole ur = new UserRole();
            ur.setUserId(id);
            ur.setRoleId(roleId);

            userRoleList.add(ur);
        });
        // 先清除关联表中当前用户所有的 关联数据
        userRoleService.remove(new QueryWrapper<UserRole>().eq("user_id", id));
        userRoleService.saveBatch(userRoleList);  // 将用户和角色的关系数据 保存到关联表
        // 用户角色改变，权限也发生改变，需要清除Redis中缓存
        User user = userService.getById(id);
        userService.clearUserAuthorityInfo(user.getUsername());
        return Result.success("用户角色分配成功");
    }

    // 重置用户密码
    @PreAuthorize("hasAuthority('sys:user:repass')")
    @PostMapping("/repass/{id}")
    public Result repass(@PathVariable Long id) {
        User user = userService.getById(id);
        // 设置 密码必须使用springSecurity 加密
        user.setPassword(passwordEncoder.encode(Const.RESET_PASSWORD));
        user.setUpdated(LocalDateTime.now());

        userService.updateById(user);
        return Result.success("用户密码重置成功");
    }

    @GetMapping("/info/{id}")
    public Result info(@PathVariable Long id) {
        User user = userService.getById(id);
        // 查询该用户的所具备的角色信息
        List<Role> roles = roleService.listRolesByUserId(user.getId());
        user.setRoles(roles);
        return Result.success(user);
    }

    @PostMapping("/update")
    public Result update(@RequestBody User user) {
        user.setUpdated(LocalDateTime.now());
        userService.updateById(user);
        return Result.success("用户信息更新成功");
    }

    @PostMapping("/save")
    public Result save(@RequestBody User user) {
        user.setCreated(LocalDateTime.now());
        // user.setStatu( Const.STATUS_ON );
        user.setPassword(passwordEncoder.encode(Const.RESET_PASSWORD));

        userService.save(user);
        return Result.success("用户信息保存成功");
    }

    @GetMapping("/list")
    public Result list(String name) {
        Page<User> users = userService.page(getPage(), new QueryWrapper<User>().like(StrUtil.isNotBlank(name), "username", name));
        // 根据用户id，查询该用户所具备的所有的角色信息
        users.getRecords().stream().forEach(u -> {
            // 循环使用 用户编号 查询用户的角色信息
            List<Role> roles = roleService.listRolesByUserId(u.getId());
            u.setRoles(roles);
        });
        return Result.success(users);
    }

    @Transactional
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('sys:user:delete')")
    public Result delete(@RequestBody Long[] ids) {
        userRoleService.remove(new QueryWrapper<UserRole>().in("user_id", ids));
        userService.removeByIds(Arrays.asList(ids));
        return Result.success("用户删除成功");
    }

    /**
     * 访问量在访问首页获取用户信息时，自动触发新增:按日期
     * 统计用户总访问量:折线图
     * @return
     */
    @GetMapping("/getFootTraffic")
    public Result getFootTraffic() {
        return userService.getFootTraffic();
    }
}
